package cn.melonlib.graphql.model.enums;

import cn.melonlib.graphql.model.scalars.GraphQLLong;
import cn.melonlib.objects.maps.JsonMap;
import graphql.GraphQLException;
import graphql.Scalars;
import graphql.language.*;
import graphql.schema.*;
import lombok.Getter;
import org.jetbrains.annotations.NotNull;

import java.util.Map;

@Getter
public enum GraphqlScalarType {
    INT(Integer.TYPE, Scalars.GraphQLInt,"number"),INTEGER(Integer.class,Scalars.GraphQLInt,"number"),
    LONG_TYPE(Long.TYPE, GraphQLLong.getLongType(),"number"),LONG(Long.class,GraphQLLong.getLongType(),"number"),
    FLOAT_TYPE(Float.TYPE,Scalars.GraphQLFloat,"number"),FLOAT(Float.class,Scalars.GraphQLFloat,"number"),
    DOUBLE_TYPE(Double.TYPE,Scalars.GraphQLFloat,"number"),DOUBLE(Double.class,Scalars.GraphQLFloat,"number"),
    BOOLEAN_TYPE(Boolean.TYPE,Scalars.GraphQLBoolean,"boolean"),BOOLEAN(Boolean.class,Scalars.GraphQLBoolean,"boolean"),
    STRING(String.class,Scalars.GraphQLString,"string"),JSON(Map.class,GraphQLScalarType.newScalar()
            .name("Map")
            .description("自由对象")
            .coercing(new Coercing<Map<String,Object>, Map<String,Object>>() {
                @Override
                public Map<String, Object> serialize(@NotNull Object dataFetcherResult) throws CoercingSerializeException {
                    if(dataFetcherResult instanceof Map m){
                        return m;
                    }
                    throw new GraphQLException("不支持的Map类型");
                }

                @Override
                public @NotNull Map<String, Object> parseValue(@NotNull Object input) throws CoercingParseValueException {
                    if(input instanceof Map m){
                        return m;
                    }
                    throw new GraphQLException("不支持的Map类型");
                }

                @Override
                public @NotNull Map<String, Object> parseLiteral(@NotNull Object input) throws CoercingParseLiteralException {
                    if(input instanceof Map m){
                        return m;
                    }
                    if(input instanceof ObjectValue value){
                        return objectValueToMap(value);
                    }
                    throw new GraphQLException("不支持的Map类型");
                }
            })
            .build(),"any");

    private final Class<?> javaType;

    private final GraphQLScalarType scalarType;

    private final String tsType;

    GraphqlScalarType(Class<?> javaType, GraphQLScalarType scalarType,String tsType) {
        this.javaType = javaType;
        this.scalarType = scalarType;
        this.tsType=tsType;
    }

    public static Map<String,Object> objectValueToMap(ObjectValue objectValue){
        return objectValue.getObjectFields().stream().reduce(JsonMap.createMap(),(m,v)->m.append(v.getName(),parseValue(v.getValue())),(m,v)->null);
    }

    public static Object parseValue(Value value){
        if(value instanceof BooleanValue booleanValue){
            return booleanValue.isValue();
        }
        if(value instanceof IntValue intValue){
            return intValue.getValue().longValue();
        }
        if(value instanceof StringValue stringValue){
            return stringValue.getValue();
        }
        if(value instanceof FloatValue floatValue){
            return floatValue.getValue().doubleValue();
        }
        if(value instanceof ObjectValue objectValue){
            return objectValueToMap(objectValue);
        }
        throw new RuntimeException("不支持的类型");
    }
}
